package com.yfbao.web.gateway.fifter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yfbao.web.gateway.ops.FastApiProxyService;
import com.yfbao.web.gateway.router.RequestRouter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;


import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
@Order(1)
public class GatewayFilter extends OncePerRequestFilter {

    private final RequestRouter requestRouter;
    private final FastApiProxyService proxyService;


    public GatewayFilter(RequestRouter requestRouter,
                         FastApiProxyService proxyService) {
        this.requestRouter = requestRouter;
        this.proxyService = proxyService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {


        String path = httpServletRequest.getRequestURI();
        String method = httpServletRequest.getMethod();

        // 1. 检查是否为FastAPI代理路径
        if (requestRouter.shouldProxyToFastApi(path)) {
            handleFastApiProxy(httpServletRequest, httpServletResponse);
            return;
        }

        // 2. 检查是否为本地业务路径

        filterChain.doFilter(httpServletRequest, httpServletResponse);

//        // 3. 其他路径返回404
//        sendNotFoundResponse(httpServletResponse, path);
    }



    private void handleFastApiProxy(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 1. 鉴权检查
//            if (!checkAuthentication(request, response)) {
//                return;
//            }

            // 2. 读取请求体（如果需要）
            String requestBody = null;
            if (hasRequestBody(request)) {
                requestBody = readRequestBody(request);
            }

            // 3. 代理请求到FastAPI
            ResponseEntity<Object> proxyResponse = proxyService.proxyRequest(request, requestBody);

            // 4. 将响应写回客户端
            writeProxyResponse(response, proxyResponse);

        } catch (Exception e) {
            log.error("处理FastAPI代理请求失败: {}", e.getMessage(), e);
            sendErrorResponse(response, HttpStatus.INTERNAL_SERVER_ERROR, "网关处理失败");
        }
    }

//    private boolean checkAuthentication(HttpServletRequest request, HttpServletResponse response) {
//        // 跳过登录等公开接口
//        if (isPublicPath(request.getRequestURI())) {
//            return true;
//        }
//
//        String token = extractToken(request);
//        if (token == null) {
//            sendErrorResponse(response, HttpStatus.UNAUTHORIZED, "缺少访问令牌");
//            return false;
//        }
//
//        try {
//            Claims claims = jwtUtil.validateToken(token);
//            // 将用户信息添加到请求属性中，供后续使用
//            request.setAttribute("userId", claims.getSubject());
//            request.setAttribute("userRoles", claims.get("roles", String.class));
//            return true;
//        } catch (Exception e) {
//            sendErrorResponse(response, HttpStatus.UNAUTHORIZED, "令牌无效或已过期");
//            return false;
//        }
//    }

    private boolean isPublicPath(String path) {
        return path.equals("/api/auth/login") || path.equals("/api/auth/register");
    }

    private String extractToken(HttpServletRequest request) {
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }
        return request.getParameter("token");
    }

    private boolean hasRequestBody(HttpServletRequest request) {
        String method = request.getMethod().toUpperCase();
        return "POST".equals(method) || "PUT".equals(method) || "PATCH".equals(method);
    }

    private String readRequestBody(HttpServletRequest request) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader reader = request.getReader();
        String line;
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line);
        }
        return stringBuilder.toString();
    }

    private void writeProxyResponse(HttpServletResponse response, ResponseEntity<Object> proxyResponse)
            throws IOException {
        // 设置状态码
        response.setStatus(proxyResponse.getStatusCodeValue());

        // 设置响应头（排除 Transfer-Encoding）
        HttpHeaders headers = proxyResponse.getHeaders();
        for (String headerName : headers.keySet()) {
            if (!"Transfer-Encoding".equalsIgnoreCase(headerName)) {
                for (String headerValue : headers.get(headerName)) {
                    response.addHeader(headerName, headerValue);
                }
            }
        }

        // 设置响应体
        Object body = proxyResponse.getBody();
        if (body != null) {
            if (!response.isCommitted()) {
                String responseBody = new ObjectMapper().writeValueAsString(body);
                response.setContentLength(responseBody.getBytes(StandardCharsets.UTF_8).length);
                response.setCharacterEncoding("UTF-8");

                String contentType = headers.getFirst("Content-Type");
                if (contentType != null) {
                    response.setContentType(contentType);
                } else {
                    response.setContentType("application/json;charset=UTF-8");
                }

                response.getWriter().write(responseBody);
            }
        }
    }


    private void sendErrorResponse(HttpServletResponse response, HttpStatus status, String message) {
        try {
            response.setStatus(status.value());
            response.setContentType("application/json;charset=UTF-8");

            Map<String, Object> error = new HashMap<>();
            error.put("error", true);
            error.put("message", message);
            error.put("timestamp", System.currentTimeMillis());

            response.getWriter().write(new ObjectMapper().writeValueAsString(error));
        } catch (IOException e) {
            log.error("发送错误响应失败: {}", e.getMessage());
        }
    }

    private void sendNotFoundResponse(HttpServletResponse response, String path) {
        sendErrorResponse(response, HttpStatus.NOT_FOUND, "路径不存在: " + path);
    }



}
